import { EventDispatcher, Raycaster, Vector2 } from 'three'

export class TEventManager extends EventDispatcher {
  raycaster = new Raycaster()
  mouse = new Vector2()
  dom
  scene
  camera
  constructor(params) {
    super()
    this.dom = params.dom
    this.scene = params.scene
    this.camera = params.camera

    const mouse = this.mouse
    const raycaster = this.raycaster
    const dom = params.dom

    let cacheObject = null

    dom.addEventListener('mousedown', () => {
      // 从鼠标位置沿着相机方向发射射线
      raycaster.setFromCamera(mouse, this.camera)
      // 获取射线穿过的所有物体
      const intersection = raycaster.intersectObjects(this.scene.children)
      // 触发全局事件，并传入射线穿过的物体数组，达到事件委派的效果
      this.dispatchEvent({
        type: 'mousedown',
        intersection,
      })
      if (intersection.length) {
        // 获取最外面的物体
        const object = intersection[0].object
        object.dispatchEvent({
          type: 'mousedown',
        })
      }
    })
    dom.addEventListener('mouseup', () => {
      // 从鼠标位置沿着相机方向发射射线
      raycaster.setFromCamera(mouse, this.camera)
      // 获取射线穿过的所有物体
      const intersection = raycaster.intersectObjects(this.scene.children)
      this.dispatchEvent({
        type: 'mouseup',
        intersection,
      })
      if (intersection.length) {
        // 获取最外面的物体
        const object = intersection[0].object
        object.dispatchEvent({
          type: 'mouseup',
        })
      }
    })
    // dom.addEventListener('mouseenter', () => {
    //   // 从鼠标位置沿着相机方向发射射线
    //   raycaster.setFromCamera(mouse, this.camera)
    //   // 获取射线穿过的所有物体
    //   const intersection = raycaster.intersectObjects(this.scene.children)
    //   this.dispatchEvent({
    //     type:"mouseenter"
    //   })
    //   if (intersection.length) {
    //     // 获取最外面的物体
    //     const object = intersection[0].object
    //     object.dispatchEvent({
    //       type: 'mouseenter',
    //     })
    //   }
    // })
    // dom.addEventListener('mouseleave', () => {
    //   // 从鼠标位置沿着相机方向发射射线
    //   raycaster.setFromCamera(mouse, this.camera)
    //   // 获取射线穿过的所有物体
    //   const intersection = raycaster.intersectObjects(this.scene.children)
    //   this.dispatchEvent({
    //     type:"mouseleave"
    //   })
    //   if (intersection.length) {
    //     // 获取最外面的物体
    //     const object = intersection[0].object
    //     object.dispatchEvent({
    //       type: 'mouseleave',
    //     })
    //   }
    // })
    dom.addEventListener('mousemove', (event) => {
      // 坐标归一化处理
      mouse.x = (event.offsetX / dom.offsetWidth) * 2 - 1
      mouse.y = -(event.offsetY * 2) / dom.offsetHeight + 1

      // 从鼠标位置沿着相机方向发射射线
      raycaster.setFromCamera(mouse, this.camera)
      // 获取射线穿过的所有物体
      const intersection = raycaster.intersectObjects(this.scene.children)
      this.dispatchEvent({
        type: 'mousemove',
        intersection,
      })
      if (intersection.length) {
        // 获取最外面的物体
        const object = intersection[0].object
        // 当选中物体是新物体，触发鼠标进入物体事件
        if (object !== cacheObject) {
          if (cacheObject) {
            cacheObject.dispatchEvent({
              type: 'mouseleave',
            })
          }
          // 手动触发物体事件
          object.dispatchEvent({
            type: 'mouseenter',
          })
        }
        // 当选中物体是原物体，触发鼠标在物体上移动事件
        else if (object === cacheObject) {
          // 手动触发物体事件
          object.dispatchEvent({
            type: 'mousemove',
          })
        }
        // 更新当前鼠标上的物体
        cacheObject = object
      } else {
        if (cacheObject) {
          cacheObject.dispatchEvent({
            type: 'mouseleave',
          })
        }
        cacheObject = null
      }
    })
    dom.addEventListener('click', () => {
      // 从鼠标位置沿着相机方向发射射线
      raycaster.setFromCamera(mouse, this.camera)
      // 获取射线穿过的所有物体
      const intersection = raycaster.intersectObjects(this.scene.children)
      this.dispatchEvent({
        type: 'click',
        intersection,
      })
      if (intersection.length) {
        // 获取最外面的物体
        const object = intersection[0].object
        object.dispatchEvent({
          type: 'click',
        })
      }
    })
  }
}
